/**
 * 全站http配置
 *
 * axios参数说明
 * isSerialize是否开启form表单提交
 */
import axios from 'axios'
import store from '@/store/';
import router from '@/router/router'
import { serialize } from '@/util/util'
import { Message } from 'element-ui'
import website from '@/config/website';
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { tokenManager } from '@/util/jwt'

const server = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 300000, // 请求超时时间
  //跨域请求，允许保存cookie
  withCredentials: true,
  //返回其他状态吗
  validateStatus (status) {
    return status >= 200 && status <= 500; // 默认的
  }
})
// NProgress Configuration
NProgress.configure({
  showSpinner: false
});

// HTTPrequest拦截公共逻辑处理方法
function applyCommonLogic(config) {
  const meta = (config.meta || {});
  //headers中配置serialize为true开启序列化
  if (config.method === 'post' && meta.isSerialize === true) {
    config.data = serialize(config.data);
  }
  return config
}

//HTTPrequest拦截
server.interceptors.request.use(async config => {
  NProgress.start() // start progress bar
  try {
    config = await tokenManager.refreshToken(config)
    config = applyCommonLogic(config)
  } catch (error) {
    return Promise.reject(error); // 将错误传递给响应拦截器
  }
  return config
}, error => {
  return Promise.reject(error)
});
//HTTPresponse拦截
server.interceptors.response.use(async res => {
  NProgress.done();
  if ([401, 403].includes(Number(res.status))) {
    //如果是401则跳转到登录页面
    store.dispatch('FedLogOut')
    router.push({ path: '/login' })
    return Promise.reject(new Error(msg))
  }
  const status = res.data?.code ?? Number(res.status);
  const statusWhiteList = website.statusWhiteList || [];
  const msg = res.data.msg || '未知错误';
  // 自定义处理响应
  if (res.config.source) return Promise.resolve(res);
  //如果在白名单里则自行catch逻辑处理
  if (statusWhiteList.includes(status)) return Promise.reject(res.data);
  // 如果请求为非200否者默认统一处理
  if (status !== 0) {
    Message({
      message: msg,
      type: 'error'
    })
    return Promise.reject(new Error(msg))
  }
  return res.data;
}, error => {
  NProgress.done();
  return Promise.reject(new Error(error));
})

export default server;